package cn.i96688.v2x.modules.netty.handler;

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.net.InetSocketAddress;

import org.apache.dubbo.config.annotation.Reference;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Component;

import cn.i96688.v2x.api.DataService;
import cn.i96688.v2x.modules.auth.AuthManager;
import cn.i96688.v2x.v2xframe.MessageFrame;
import cn.i96688.v2x.v2xframe.Response;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.channel.Channel;
import io.netty.channel.ChannelHandler;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import io.netty.channel.socket.DatagramPacket;
import io.netty.util.concurrent.EventExecutorGroup;
/**
 * UDP业务处理handler
 * @author xys
 *
 */
@ChannelHandler.Sharable
@Component
public class UdpServerHandler extends SimpleChannelInboundHandler<DatagramPacket> {
	private final static Logger LOGGER = LoggerFactory.getLogger(UdpServerHandler.class);
	@Autowired
	@Qualifier("businessGroup")
	private EventExecutorGroup businessGroup;
	@Autowired
	private AuthManager authManager;
	@Reference(check=false)
	private DataService dataService;
	
	@Override
    public void channelRead0(ChannelHandlerContext ctx, DatagramPacket packet) throws Exception {
		ByteBuf buf = packet.content();
		int len=buf.readableBytes();
		if (len <= 0) {
			return;
		}
		byte[] bs=new byte[len];
		buf.readBytes(bs);
		businessGroup.execute(()->{
			try {
				MessageFrame frame=MessageFrame.per_decode(false, new ByteArrayInputStream(bs));
				Response resp=null;
				//鉴权成功
				if(authManager.checkAuth(frame.getId())){
					//发送到业务后台	
					dataService.save(bs);
					resp=Response.success("ok");
				}else {
					resp=Response.fail("没有登录");
				}
				send2client(ctx.channel(),resp, packet.sender());
			}catch(Throwable e) {
				LOGGER.error("UDP数据处理出错",e);
				Response resp=Response.fail("系统错误");
				send2client(ctx.channel(),resp, packet.sender());
			}
		});
    }

    @Override
    public void channelReadComplete(ChannelHandlerContext ctx) {
        ctx.flush();
    }

    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {
    	LOGGER.error("UDP数据接收处理出错：",cause);
    }
    /**
     * 返回消息给客户端
     * @param channel
     * @param msg
     * @param address
     */
    void send2client(Channel channel,Response resp,InetSocketAddress address) {
    	try {
			channel.writeAndFlush(new DatagramPacket(Unpooled.copiedBuffer(resp.encode()), address));
		} catch (IOException e) {
			LOGGER.error("UDP发送数据给客户端出错：",e);
		}
    }
}
